﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OleDb;
using System.Text;
using System.Xml;
using System.IO;
using System.Net;

/// <summary>
/// CreateMyNewsHtml 的摘要说明
/// </summary>
public class CreateMyNewsHtml
{
	public CreateMyNewsHtml()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
    public void CreateNewsContentAuto()
    {
        OleDbConnection newCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        OleDbCommand getNewsLink = new OleDbCommand("select RssNews.SiteId,insertOrder,title,pubDate,link,SiteKind,newsPageTempId from RssNews inner join Sites on RssNews.siteId = Sites.SiteId where haveNewsDetail=0", newCon);
        try
        {
            newCon.Open();
            OleDbDataReader newsReader = getNewsLink.ExecuteReader();
            while (newsReader.Read())
            {
                if (newsReader[6].ToString() != "无")
                {
                    SiteNewsDetailHandle(newsReader[0].ToString(), newsReader[1].ToString(), newsReader[2].ToString(), newsReader[3].ToString(), newsReader[4].ToString(), newsReader[5].ToString(), newsReader[6].ToString());
                }
            }
            newsReader.Close();
        }
        finally
        {
            newCon.Close();
        }       
    }
    public void DeleteNews(string date)
    {
        OleDbConnection con = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        OleDbCommand cmd = new OleDbCommand("select NewsId from MyNewsDetailList where InsertDate <= #" + date + "#", con);
        OleDbCommand delCmd = new OleDbCommand("delete from MyNewsDetailList where InsertDate <= #" + date + "#", con);
        FileInfo file;
        try
        {
            con.Open();
            OleDbDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                file = new FileInfo(HttpRuntime.AppDomainAppPath + "newsdetail\\" + reader[0].ToString() + ".html");
                if (file.Exists)
                {
                    file.Delete();
                }
            }
            reader.Close();

            delCmd.ExecuteNonQuery();
        }
        catch
        {
        }
        finally
        {
            con.Close();
        }       
    }
    /// <summary>
    /// 处理生成新闻内容页面
    /// </summary>
    /// <param name="siteId">新闻来源站点ID</param>
    /// <param name="newsId">新闻ID</param>    
    /// <param name="rssTitle">rss中的新闻标题</param>
    /// <param name="pubDate">日期</param>
    /// <param name="url">原站点url</param>
    /// <param name="siteKind">新闻类别</param>
    /// <param name="templateId">新网页面内容提取模板ID</param>
    public void SiteNewsDetailHandle(string siteId, string newsId, string rssTitle, string pubDate, string url, string siteKind, string templateId)
    {
        string newsTitle, newsContent;
        string mainS = "", mainE = "", titleS = "", titleE = "", titleDelS = "", titleDelE = "",
            bodyS = "", bodyE = "", removeTag = "", delStart = "", delEnd = "", pageEncode = "";
        int mainLen, titleLen, bodyLen, removeNum = 1;
        bool begin = true;
        XmlDocument docPage = new XmlDocument();
        string xmlPath = HttpRuntime.AppDomainAppPath.ToString() + "App_Data\\SiteHtmlNewsTag.xml";
        docPage.Load( xmlPath);
        XmlElement root = docPage.DocumentElement;
        XmlNodeList sites = root.ChildNodes;
        foreach (XmlNode s in sites)
        {
            if (s.Attributes["id"].Value == templateId)//查找正确的站点节点
            {
                mainS = s.SelectSingleNode("mainStart").InnerText;
                mainE = s.SelectSingleNode("mainEnd").InnerText;
                titleS = s.SelectSingleNode("titleStart").InnerText;
                titleE = s.SelectSingleNode("titleEnd").InnerText;
                titleDelS = s.SelectSingleNode("titleDelStart").InnerText;
                titleDelE = s.SelectSingleNode("titleDelEnd").InnerText;
                bodyS = s.SelectSingleNode("bodyStart").InnerText;
                bodyE = s.SelectSingleNode("bodyEnd").InnerText;
                removeTag = s.SelectSingleNode("removeTag").InnerText;
                removeNum = int.Parse(s.SelectSingleNode("removeNum").InnerText);
                begin = s.SelectSingleNode("begin").InnerText == "true" ? true : false;
                delStart = s.SelectSingleNode("deleteStartTags").InnerText;
                delEnd = s.SelectSingleNode("deleteEndTags").InnerText;
                pageEncode = s.Attributes["pageEncode"].Value;
                break;
            }
        }
        url = url.Substring(url.LastIndexOf("http:"));
        string siteUrl = url.Substring(0, url.LastIndexOf('/') + 1);
        byte[] htmlNews;
        try
        {
            htmlNews = new WebClient().DownloadData(url);
        }
        catch
        {
            return;
        }
        string sourceCode = Encoding.GetEncoding(pageEncode).GetString(htmlNews);

        bool mBool = CutPage(mainS, mainE, ref sourceCode);
        if (!mBool)
        {
            UpdateRssNewsTable(newsId, "3"); return;
        }
        string title = GetTitle(titleS, titleE, sourceCode, titleDelS, titleDelE);
        CutBody(bodyS, bodyE, ref sourceCode, removeTag, begin, removeNum, delStart, delEnd);
        ReplaceHrefImgInContent(siteUrl, ref sourceCode);
        if (CreateNewsDetailPage(newsId, title, sourceCode, url, siteKind))//是否成功 生成新闻内容页面
        {
            UpdateRssNewsTable(newsId, "1");
            InsertMyNewsDetail(newsId, rssTitle, pubDate, siteId, siteKind);
        }
        else
        {
            UpdateRssNewsTable(newsId, "3");
        }
    }
    protected void UpdateRssNewsTable(string newsId, string state)
    {
        OleDbConnection con = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        OleDbCommand cmd = new OleDbCommand("update RssNews set haveNewsDetail=" + state + " where insertOrder=" + newsId, con);
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        catch
        {
        }
        finally
        {
            con.Close();
        }
    }
    protected void InsertMyNewsDetail(string id, string title, string pubDate, string siteId, string siteKind)
    {        
        OleDbConnection hCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        OleDbCommand hCmd = new OleDbCommand("select count(*) from MyNewsDetailList where NewsId=" + id, hCon);
        string haveId = "0";
        try
        {
            hCon.Open();
            haveId = hCmd.ExecuteScalar().ToString();
        }
        finally
        {
            hCon.Close();
        }
        if (haveId != "0")
        {
            return;
        }
        title = title.Replace("&nbsp;", "　");
        title = title.Length > 50 ? title.Substring(0, 50) : title;
        OleDbConnection con = new OleDbConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        OleDbCommand cmd = new OleDbCommand("insert into MyNewsDetailList(NewsId, NewsTitle, PubDate, SiteId, SiteKind) values(" + id + ",?,'" + pubDate + "'," + siteId + ",'" + siteKind + "')", con);
        cmd.Parameters.Add("NewsTitle", OleDbType.VarWChar, 50).Value = title;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        catch
        {
        }
        finally
        {
            con.Close();
        }
    }
    /// <summary>
    /// 生成新闻内容页面
    /// </summary>
    /// <param name="htmlId">新闻页面ID</param>
    /// <param name="title">标题</param>
    /// <param name="content">内容</param>
    /// <param name="url">原始新闻url</param>
    /// <param name="siteKind">所属的新闻类别</param>
    /// <returns>是否生成成功</returns>
    protected bool CreateNewsDetailPage(string htmlId, string title, string content, string url, string siteKind)
    {
        try
        {
            using (StreamWriter w = new StreamWriter(HttpRuntime.AppDomainAppPath + "newsdetail\\" + htmlId + ".html", false, System.Text.Encoding.GetEncoding("GB2312")))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(HttpRuntime.AppDomainAppPath + "App_Data\\NewsContentTemplate.xml");
                XmlElement root = doc.DocumentElement;

                w.Write(root.SelectSingleNode("htmlHead").InnerText + title + ",图科新闻 Too OK! www.toook.com Id=" + htmlId + root.SelectSingleNode("htmlTitleEnd").InnerText +
                    root.SelectSingleNode("htmlContentTitle").InnerText + "<span id='visitPage'>" + htmlId + "</span>" + title +
                    root.SelectSingleNode("htmlContentHead").InnerText + content + "<br /><span class='source'><a href='" + url + 
                    "' target='_blank'>查看原新闻</a></span><a id='moreNews' href='../newsList.aspx?type=" + siteKind + "'>更多新闻</a>" + 
                    root.SelectSingleNode("htmlEnd").InnerText);
                w.Close();
            }
            //errorMsg = "";
            return true;
        }
        catch (Exception exs)
        {
            //errorMsg = exs.Message;
            return false;
        }
    }
    /// <summary>
    /// 截取主要内容
    /// </summary>
    /// <param name="startTag">开始标记</param>
    /// <param name="endTag">结束标记</param>
    /// <param name="content">传入源文件，输出截取后的内容</param>
    /// <returns>是否成功</returns>
    protected bool CutPage(string startTag, string endTag, ref string content)
    {
        int start=-1, end=-1;
        start = content.IndexOf(startTag);
        if (start < 0)
        {
            return false;
        }
        if (endTag.IndexOf(',') > -1)
        {
            string[] endPos = endTag.Split(',');
            for (int kkk = 0; kkk < endPos.Length; kkk++)
            {
                end = content.IndexOf(endPos[kkk], start);
                if (end > -1)
                {
                    break;
                }
            }
        }
        else
        {
            end = content.IndexOf(endTag, start);
        }
        if (end < 0)
        {
            return false;
        }
        start += startTag.Length;
        content = content.Substring(start, end - start);//求得标题
        return true;
    }
    /// <summary>
    /// 截取文章内容
    /// </summary>
    /// <param name="startTag">文章开始标签，没有为空</param>
    /// <param name="endTag">文章结束大标记，没有为空</param>
    /// <param name="content">文章内容</param>
    /// <param name="removeEnd">文章结束精确标记,没有为空</param>
    /// <param name="begin">正数还是倒数搜索，true正数</param>
    /// <param name="nTag">搜索第几个精确标记,从1开始</param>
    /// <param name="delStartTag">删除的开始标记串,没有为空</param>
    /// <param name="delEndTag">删除的结束标记串，与开始配对</param>
    /// <returns></returns>
    protected bool CutBody(string startTag, string endTag, ref string content, string removeEnd, bool begin, int nTag, string delStartTag, string delEndTag)
    {
        int start, end;
        start = startTag == "" ? 0 : content.IndexOf(startTag) + startTag.Length;
        end = endTag == "" ? content.Length : content.IndexOf(endTag, start);
        if (start < 0 || end < 0)
        {
            return false;
        }
        content = content.Substring(start, end - start);//求得内容
        if (removeEnd != "")
        {
            start = 0;//设置开始搜索位置
            int temp = 0;
            if (begin)
            {
                for (int i = 0; i < nTag; i++)
                {
                    temp = content.IndexOf(removeEnd, start);
                    if (temp == -1)
                    {
                        break;
                    }
                    else
                    {
                        start = temp;
                    }
                }
            }
            else
            {
                end = start = content.Length - 1;
                for (int i = 0; i < nTag; i++)
                {
                    temp = content.LastIndexOf(removeEnd, start);
                    if (temp == -1)
                    {
                        break;
                    }
                    else
                    {
                        start = temp;
                    }
                }
                //if (end == start) { start = 0; }
            }
            if (start > 0)
            {
                content = content.Remove(start);
            }
        }
        if (delStartTag != "")//删除文章中的标记
        {
            string[] delS, delE;
            delS = delStartTag.Split(',');
            delE = delEndTag.Split(',');
            int dn = delS.Length;
            for (int k = 0; k < dn; k++)
            {
                bool tagHave = true;
                while (tagHave)//搜索其中一个标记的所有匹配文本
                {
                    start = content.IndexOf(delS[k]);
                    if (start > -1)
                    {
                        end = content.IndexOf(delE[k], start);
                        if (end > -1)
                        {
                            content = content.Remove(start, end - start + delE[k].Length);//删除匹配标记的内容
                        }
                        else
                        {
                            tagHave = false;
                        }
                    }
                    else
                    {
                        tagHave = false;
                    }
                }
            }
        }
        return true;
    }
    /// <summary>
    /// 替换网站链接、图片为绝对路径
    /// </summary>
    /// <param name="siteUrl">当前网页的路径，到最后一个/处，如http://toook.com/news/fiance/  一定要加最后的/</param>
    /// <param name="content"></param>
    protected void ReplaceHrefImgInContent(string siteUrl, ref string content)
    {  
        int start, end;
        int[] pos = { 0, 0, 0, 0 };
        string[] typeList = { "href=","HREF=", "src=", "SRC=" };
        for (int typeN = 0; typeN < typeList.Length; typeN++)
        {
            while (true)
            {
                start = content.IndexOf(typeList[typeN], pos[typeN]);
                if (start > -1)
                {
                    pos[typeN] = start + typeList[typeN].Length;
                    start = pos[typeN];
                    char[] cc = {'>', '='};
                    end = content.IndexOfAny(cc, start);
                    if (end > -1)
                    {
                        if (end - start > 200)//如果.距离href太远，说明不是自己的地址
                        {
                            break;
                        }
                        int temp = content.IndexOf("http:", start, 10);
                        if (temp > -1)
                        {
                            pos[typeN] = start = temp + 5;
                            continue;
                        }
                        else
                        {
                            string tStr = content.Substring(start, end - start);//取得图片地址部分
                            int t = tStr.Length;
                            for (int k = 0; k < t; k++)
                            {
                                if (tStr.Substring(k, 1) == "/")
                                {
                                    content = content.Insert(start + k, siteUrl.Substring(0, siteUrl.IndexOf('/', 10)));
                                    break;
                                }
                                else if (tStr.Substring(k, 1) == ".")
                                {
                                    int pp = tStr.LastIndexOf("../");
                                    if (pp < 0)//路径不对
                                    {
                                        break;
                                    }
                                    else if (pp == 0)//没有引号
                                    {
                                        content = content.Remove(start, 3);
                                        content = content.Insert(start, siteUrl.Substring(0, siteUrl.LastIndexOf('/', siteUrl.Length - 2) + 1));
                                        break;
                                    }
                                    else if (pp == 1)//有引号
                                    {
                                        content = content.Remove(start + 1, 3);
                                        content = content.Insert(start + 1, siteUrl.Substring(0, siteUrl.LastIndexOf('/', siteUrl.Length - 2) + 1));
                                        break;
                                    }
                                    else
                                    {
                                        int rrr = pp / 3 + 1;

                                        string tUrl = siteUrl;
                                        for (int i = 0; i < rrr; i++)
                                        {
                                            tUrl = tUrl.Substring(0, tUrl.LastIndexOf('/', tUrl.Length - 2) + 1);
                                        }
                                        if (pp % 3 != 0)
                                        {
                                            content = content.Remove(start + 1, pp + 2);
                                            content = content.Insert(start + 1, tUrl);
                                        }
                                        else
                                        {
                                            content = content.Remove(start, pp + 3);
                                            content = content.Insert(start, tUrl);
                                        }
                                        break;
                                    }
                                }
                                else if (tStr.Substring(k, 1) == "\"" || tStr.Substring(k, 1) == "'" || tStr.Substring(k, 1) == " ")
                                {
                                    continue;
                                }
                                else//不是空格，" or ' or /
                                {
                                    content = content.Insert(start + k, siteUrl); break;
                                }
                            }
                        }
                    }
                    else//没有结束标记，跳出循环
                    {
                        break;
                    }
                }
                else//没有开始标记，跳出循环
                {
                    break;
                }
            }
        }
    }
    /// <summary>
    /// 取得文章标题
    /// </summary>
    /// <param name="startTag">标题开始标签，没有为空串</param>
    /// <param name="endTag">标题结束标签，没有为空串</param>
    /// <param name="content">传入源代码</param>
    /// <param name="startDel">删除开始标记，没有为空串</param>
    /// <param name="endDel">删除结束标记，没有为空串</param>
    /// <returns>返回文章标题</returns>
    protected string GetTitle(string startTag, string endTag, string content, string startDel, string endDel)
    {
        int start, end;
        //if (startTag == "")
        //{
        //    start = 0;
        //}
        //else
        //{
        //    if (startTag.IndexOf('>') > -1)
        //    {
        //        start = content.IndexOf(startTag) + startTag.Length;
        //    }
        //    else
        //    {
        //        int n = content.IndexOf(startTag);
        //        if (n > -1)
        //        {
        //            start = content.IndexOf('>', content.IndexOf(startTag)) + 1;
        //        }
        //        else
        //        {
        //            start = content.IndexOf('>') > -1 ? content.IndexOf('>') + 1 : 0;
        //        }
        //    }
        //}
        start = startTag == "" ? 0 : content.IndexOf(startTag);// +startTag.Length;
        end = endTag == "" ? 0 : content.IndexOf(endTag);
        if (start < 0 || end < 0)
        {
            return "标题";
        }
        start += startTag.Length;
        content = content.Substring(start, end - start);//求得标题
        if (startDel != "")
        {
            content = content.Substring(content.LastIndexOf(startDel) + startDel.Length);
        }
        if (endDel != "")
        {
            content = content.Substring(0, content.IndexOf(endDel));
        }
        return content;
    }    
}
